package com.scg33.inicio;

// nuevo
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;

import org.zkoss.calendar.Calendars;
import org.zkoss.calendar.api.CalendarEvent;
import org.zkoss.calendar.api.DateFormatter;
import org.zkoss.calendar.event.CalendarsEvent;
import org.zkoss.calendar.impl.SimpleCalendarModel;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Path;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.sys.EventListenerMap;
import org.zkoss.zkmax.bind.impl.AnnotateBinderEx;

import org.zkoss.zul.Datebox;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Timebox;
import org.zkoss.zul.Window;

import com.coreweb.componente.BodyPopupAceptarCancelar;
import com.coreweb.componente.VerificaAceptarCancelar;
import com.coreweb.util.Misc;
import com.scg33.dominio.CalendarioEvento;
import com.scg33.dominio.RegisterDomain;
import com.scg33.inicio.calendario.CalendarioDatoModelo;
import com.scg33.inicio.calendario.PMSDateFormatter;
import com.sun.swing.internal.plaf.basic.resources.basic_pt_BR;

public class VMCalendar extends VMInicio {

	String FORMATO_FECHA_POPUP = m.DD_MM__YYY_HORA_MIN;
	
	Calendars cal;

	
	
	
	
	@Init(superclass = true)
	public void initVMCalendar() {
		this.dto = this.getSessionAcceso();
	}

	@AfterCompose(superclass = true)
	public void afterComposeVMCalendar(
			@ContextParam(ContextType.VIEW) Component view) {

		this.cal = (Calendars) view.getFellow("cal");
		MyCalendarsEvent mce = new MyCalendarsEvent("EventosCalendario", cal,
				null, null, null, 0, 0, 0, 0);
		mce.setVmCal(this);
		this.cal.addEventListener(CalendarsEvent.ON_EVENT_EDIT, mce);
		this.cal.addEventListener(CalendarsEvent.ON_EVENT_CREATE, mce);
	}

	
	// =================================================
	PMSDateFormatter p =  new PMSDateFormatter();
	public DateFormatter getDateFormatter(){
		return p;
	}
	
	
	// =================================================
	
	
	public CalendarioDatoModelo getCalendarModel() {
		return this.dto.getCalendarioModelo();
	}

	public void addCallendarioEvento(int left, int top, CalendarsEvent evt, boolean adm) throws Exception {
		long hasta = evt.getBeginDate().getTime()+(1000*60*60); // sumo 1 hora

		CalendarioEvento ce = new CalendarioEvento();
		ce.setIdCapitulo(this.dto.getCapituloId());
		ce.setBeginDate(evt.getBeginDate());
		ce.setEndDate(new Date(hasta));
		ce.setContent("");
		
		System.out.println("\n\n\n===============================");
		System.out.println(ce.getBeginDate().toString());
		System.out.println(ce.getEndDate().toString());
		System.out.println("=======================\n\n\n");


		boolean siAdd = showCalendarioEvento(left, top, ce, true, adm);
		if (siAdd == true) {
			this.dto.getCalendarioModelo().add(ce);
			
			this.saveDominio(ce);
			
			BindUtils.postNotifyChange(null, null, this, "*");
		}

	}

	public void editCalendarioModelo(int left, int top, CalendarsEvent evt,
			boolean adm) throws Exception {
		CalendarioEvento ce = (CalendarioEvento) evt.getCalendarEvent();
		CalendarioEvento ceAux = ce.getCopia();
		
	

		boolean siAdd = showCalendarioEvento(left, top, ceAux, false, adm);
		if (siAdd == true) {

			long desdeAux = ceAux.getBeginDate().getTime();
			long hastaAux = ceAux.getEndDate().getTime();

			if (hastaAux <= desdeAux) {
				String msg = "La fecha de fin es menor que la de inicio.\n "
						+ "Este evento será eliminado.\n\n"
						+ "Confirma que desea eliminar el evento?";
				if (this.m.mensajeSiNo(msg) == true) {
					this.dto.getCalendarioModelo().remove(ce);
					this.deleteDominio(ce);
				}
			} else {
				ce.setCalendarioEvento(ceAux);
			}
			BindUtils.postNotifyChange(null, null, this, "*");
		}

	}

	private boolean showCalendarioEvento(int left, int top,
			CalendarioEvento ce, boolean controlFechas, boolean adm) {
		boolean out = true;

		Datebox dBegin = new Datebox(ce.getBeginDate());
		dBegin.setFormat(FORMATO_FECHA_POPUP);
		dBegin.setPlaceholder(FORMATO_FECHA_POPUP);
//		dBegin.setFormat(this.m.DD_MM_YYYY);
//		dBegin.setPlaceholder(this.m.DD_MM_YYYY);
		dBegin.setWidth("250px");
		// Timebox dBeginTime = new Timebox(new Date());
		// Hlayout hBegin = new Hlayout();
		// hBegin.getChildren().add(dBegin);
		// hBegin.getChildren().add(dBeginTime);

		Datebox dEnd = new Datebox(ce.getEndDate());
		dEnd.setFormat(FORMATO_FECHA_POPUP);
		dEnd.setPlaceholder(FORMATO_FECHA_POPUP);
//		dEnd.setFormat(this.m.DD_MM_YYYY);
//		dEnd.setPlaceholder(this.m.DD_MM_YYYY);
		dEnd.setWidth("250px");
		// Timebox dEndTime = new Timebox(new Date());
		// Hlayout hEnd = new Hlayout();
		// hEnd.getChildren().add(dEnd);
		// hEnd.getChildren().add(dEndTime);

		Textbox contenido = new Textbox(ce.getContent());
		contenido.setRows(5);
		contenido.setCols(30);
		contenido.setPlaceholder("Descripción del evento");

		BodyPopupAceptarCancelar bAC = new BodyPopupAceptarCancelar();
		bAC.addComponente("Desde", dBegin);
		bAC.addComponente("Hasta", dEnd);
		bAC.addComponente("Descripción", contenido);
		bAC.setHighWindows("270px");
		VerificarEventoCalendario checkAC = new VerificarEventoCalendario(
				controlFechas);
		checkAC.setdBegin(dBegin);
		checkAC.setdEnd(dEnd);
		checkAC.setContenido(contenido);

		bAC.setCheckAC(checkAC);
		if (adm == false) {
			// no es administrador
			bAC.setSoloBotonCerrar();
		}
		
		bAC.showPopup("Evento del calendario");

		out = bAC.isClickAceptar();
		if (out == true) {
			ce.setBeginDate(dBegin.getValue());
			ce.setEndDate(dEnd.getValue());
			ce.setContent(contenido.getValue());
		}
		return out;
	}

	//=============================================================
	//control the calendar position
    @Command
    @NotifyChange ("*")
    public void gotoToday(){
        TimeZone timeZone = this.cal.getDefaultTimeZone();
        this.cal.setCurrentDate(Calendar.getInstance(timeZone).getTime());
    }

    @Command
    @NotifyChange ("*")
    public void gotoNext(){
        this.cal.nextPage();
    }

    @Command
    @NotifyChange ("*")
    public void gotoPrev(){
    	this.cal.previousPage();
    }
     
    //control page display

    @Command
    @NotifyChange ("*")
    public void changeToDay(){
    	this.cal.setMold("default");
    	this.cal.setDays(1);
    }

    @Command
    @NotifyChange ("*")
    public void changeToWeek(){
    	this.cal.setMold("default");
    	this.cal.setDays(7);
    }

    @Command
    @NotifyChange ("*")
    public void changeToYear(){
    	this.cal.setMold("month");
    }

	
}

class MyCalendarsEvent extends CalendarsEvent implements EventListener {

	Misc m = new Misc();
	VMCalendar vmCal;

	public MyCalendarsEvent(String name, Component target, CalendarEvent ce,
			Date beginDate, Date endDate, int x, int y, int dtwd, int dthgh) {
		super(name, target, ce, beginDate, endDate, x, y, dtwd, dthgh);
		// TODO Auto-generated constructor stub
	}

	public void setVmCal(VMCalendar vmCal) {
		this.vmCal = vmCal;
	}

	@Override
	public void onEvent(Event evento) throws Exception {
		CalendarsEvent evt = (CalendarsEvent) evento;

		AccesoDTO dto = this.vmCal.getSessionAcceso();
		boolean adm = dto.isSiAdministrador();

		
		int left = evt.getX();
		int top = evt.getY();

		if (top + 245 > evt.getDesktopHeight())
			top = evt.getDesktopHeight() - 245;
		if (left + 410 > evt.getDesktopWidth())
			left = evt.getDesktopWidth() - 410;
		
		String eventoNombre = evento.getName();
		if (eventoNombre.compareTo(CalendarsEvent.ON_EVENT_EDIT) == 0) {
			// editar
			this.vmCal.editCalendarioModelo(left, top, evt, adm);
		} else if ((adm == true)
				&& (eventoNombre.compareTo(CalendarsEvent.ON_EVENT_CREATE) == 0)) {

			// agregar nuevo
			this.vmCal.addCallendarioEvento(left, top, evt, adm);
		}
		evt.stopClearGhost();

	}

}

class VerificarEventoCalendario implements VerificaAceptarCancelar {

	Misc m = new Misc();
	boolean controlFecha = true;
	Datebox dBegin;
	Datebox dEnd;
	Textbox contenido;

	public VerificarEventoCalendario(boolean controlFechas) {
		this.controlFecha = controlFechas;
	}

	String textoErr = "";

	@Override
	public boolean verificarAceptar() {
		this.textoErr = "";
		boolean out = true;
		long desde = dBegin.getValue().getTime();
		long hasta = dEnd.getValue().getTime();
		
		if (desde == hasta){
			hasta = hasta + (1000*60*60); // sumo un ahora
//			dEnd.setValue(new Date(hasta));
			dEnd.getValue().setTime(hasta);
		}


		if ((this.controlFecha == true) && (desde >= hasta)) {
			this.textoErr += "La fecha inicio no puede ser menor que la fecha final.\n";
			out = false;
		}

		String cnt = this.contenido.getValue();
		if ((cnt == null) || (cnt.trim().length() == 0)) {
			this.textoErr += " Debe ingresar una descripción del evento.\n";
			out = false;
		}

		return out;
	}

	@Override
	public String textoVerificarAceptar() {
		return this.textoErr;
	}

	@Override
	public boolean verificarCancelar() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public String textoVerificarCancelar() {
		// TODO Auto-generated method stub
		return null;
	}

	public Datebox getdBegin() {
		return dBegin;
	}

	public void setdBegin(Datebox dBegin) {
		this.dBegin = dBegin;
	}

	public Datebox getdEnd() {
		return dEnd;
	}

	public void setdEnd(Datebox dEnd) {
		this.dEnd = dEnd;
	}

	public Textbox getContenido() {
		return contenido;
	}

	public void setContenido(Textbox contenido) {
		this.contenido = contenido;
	}

	
	
	
}
